Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds PostgreSQL master-replica read/write routing functionality to support database scalability. The implementation introduces a custom routing session that directs write operations to the master database while allowing read operations to use a replica database.
Changes:
- New database routing infrastructure with
RoutingSessionclass that routes database operations between master and replica - Configuration options for single or master-replica database modes
- Master database availability checks added to all write API endpoints
- Error handling for database unavailability with OperationalError suppression and user-facing error responses
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| app/database.py | New file implementing RoutingSession for master-replica routing and engine configuration |
| app/config.py | Added replica database configuration fields and removed engine property from Settings |
| app/ioc.py | Modified session factory to support routing mode, removed engine provider |
| app/api/utils.py | New utility function to check master database availability before write operations |
| app/multidirectory.py | Updated to use engines dictionary instead of settings.engine |
| tests/conftest.py | Updated test configuration to use engines dictionary |
| app/ldap_protocol/ldap_requests/base.py | Added RESPONSE_TYPE class variable and OperationalError handling in request handlers |
| app/ldap_protocol/ldap_requests/*.py | Added RESPONSE_TYPE class variable to request classes |
| app/ldap_protocol/ldap_requests/bind.py | Added OperationalError suppression for user login attribute updates |
| app/ldap_protocol/session_storage/repository.py | Added OperationalError suppression for session key creation |
| app/api/**/router*.py | Added check_master_db dependency to write endpoints |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
0cbb784 to
7891162
Compare
…nations and MFA callback
…pdate session handling
…ndencies across routers
bb71287 to
676b0b6
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
milov-dmitriy
approved these changes
Feb 6, 2026
…rganizing imports
rimu-stack
approved these changes
Feb 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Задача 1161
Изменения:
Settingsдобавлены:Engineпод реплику.single\replication.EngineRegistry, который включает в себяengineмастера и реплики.RoutingSession, отнаследованный отSession. В классе переопределены два метода:get_bind- метод, к которому обращается сессия перед выполнением запроса в базу (в момент вызовов.flush(),.execute(),.scalarsи т.д.) для получения бинда -EngineилиConnection.flush- в метод добавлено выставление дополнительного флага_force_masterдля чтения после записи.RESPONSE_TYPE(новый ClassVar для реквестов) нашего запроса со статус кодомLDAPCodes.UNAVAILABLE.Новый flow:
single- одна база и для чтения и для записи, то ничего не меняется, RoutingSession не используется.replication- то во время каждого запроса в базу мы в методеget_bindопределяем в каком мы сейчас состоянии сессии:_force_master, отдаем движок мастера._force_masterуже выставлен, значит отдаем движок мастера. (Например, случай Modify запроса, мы сначала выполняем запросы поиска в реплику, после этого выполняем flush для новой директории и в дальнейшем чтение в рамках запроса идет только из мастера)Открытые вопросы
sessionвioc? - там происходитsession.commit(). Если нам прилетитModifyзапрос во время отвала мастера мы упадем в.handleметоде с эксепшеномOperationalError, оно обработается выше в методе_handle_tcp\_handle_apiвbase.pyи LDAP нормально вернет ответ клиенту со статус кодомLDAPCodes.UNAVAILABLE, но при этом выйдет исключение вioc.pyуже после возвращения ответа клиенту. В целом не влияет на работу, но нужно как-то захендлить.